package de.uni_mannheim.informatik.ai.dame_ai.main.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;

import de.uni_mannheim.informatik.ai.dame_ai.main.application.GameProperty;
import de.uni_mannheim.informatik.ai.dame_ai.main.application.GameSettings;
import de.uni_mannheim.informatik.ai.dame_ai.main.ui.MainMenuDictionary.Phrases;

public class GameChooserPanel extends ObservablePanel{
	GameSettings gameSettings;
	GameProperty[] games;
	File selectedGame;
	String selectedGameString;
	File dir;
	ArrayList<JButton> gamesThumbs= new ArrayList<JButton>();
	JLabel gamePhoto = new JLabel();
	GameWrapper[] wrapper;
	int currentWrapperIndex;
	int height;
	int width;
	JButton exitButton = new JButton();
	BufferedImage exit;
	String[] gameNames, gameInfo;
	public GameChooserPanel(int width, int height, File imagePath, GameProperty[] games, GameSettings gameSettings){
		super(width,height,imagePath);
		this.width = width;
		this.height = height;
		this.games = games;
		this.gameSettings = gameSettings;
		mainDict = MainMenuDictionary.getDictionary(gameSettings.getLanguage());
		this.langButton.setText(mainDict.translate(Phrases.main_language));
		gameNames = new String[]{mainDict.translate(Phrases.main_playGame_dame)};
		gameInfo = new String[]{mainDict.translate(Phrases.main_gameInfo_dame)};
		try {
			exit = ImageIO.read(new File("media/main/main_exit.png"));
		} catch (IOException e) {}
		calculateGeneralBounds(width,height);
		//setSize(width, height);
		setPaneLayout(null);
		dir = new File("gameProperties");
		wrapper = createGameWrapper(imagePath, games);
		loadimages.execute();
		insertImage(image);
		//setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
		//insertGames();
		
	}

	/*public void insertGames(){
		try {
			System.out.println("Dir: "+dir.getCanonicalPath()+" "+dir.getAbsolutePath());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		games = dir.list();
		if(games != null)for(String game : games){
			System.out.println(game);
			addToPane(addAButton(game));
		}
		
	}*/
	Rectangle left = new Rectangle();
	Rectangle scroll= new Rectangle();
	Rectangle image= new Rectangle();
	Rectangle text= new Rectangle();
	Rectangle control= new Rectangle();
	int buttonIndex;
	@Override
	public void calculateGeneralBounds(){
		super.calculateGeneralBounds();
		calculateGeneralBounds(pane.getWidth(),pane.getHeight());
		insertLeftElements(left);
		insertImage(image);
		insertText(text);
		insertControl(control);
		pane.remove(exitButton);
		insertExitButton();
	}
	private void calculateGeneralBounds(int width, int height){
		
		System.err.println("REPAINTING");
		if(width/height >= 5/3){
			thumbnailSize.height = 129*height/768;
			thumbnailSize.width = thumbnailSize.height*188/129;
			left.width = thumbnailSize.width +20;
			image.height = 450*height/768;
			image.width = image.height*600/450;
		}
		else{
			left.width=188*width/1100 + 20;
			thumbnailSize.width = left.width-20;
			thumbnailSize.height = thumbnailSize.width*129/188;
			image.width= 600*width/1100;
			image.height = image.width*450/600;
			
		}
		left.height = height;
		scroll.height = height;
		scroll.width = width - image.width - left.width;
		control.width = image.width;
		text.width = image.width;
		text.height= (height - image.height)/5*2;
		control.height = (height - image.height)/5*2;
		left.x = 0;
		left.y = 0;
		scroll.x = left.width;
		scroll.y = 0;
		image.x = width - image.width;
		image.y = 0;
		text.x = image.x;
		text.y = image.height;
		control.x= image.x;
		control.y = height - control.height;
		
		//if(thumbnailSize.height<75)thumbnailSize.height = 75;
	}
	Dimension thumbnailSize=new Dimension();
	
	private void insertLeftElements(Rectangle bounds){
		for(JButton button : gamesThumbs){
			pane.remove(button);
		}
		int countThumbs = (bounds.height/thumbnailSize.height) -1;
		int x = 5;
		int y = 30;
		for(int i = buttonIndex; i< gamesThumbs.size() && i < countThumbs;i++){
			Rectangle boundsThumb = new Rectangle(x,y,thumbnailSize.width,thumbnailSize.height);
			gamesThumbs.get(i).setBounds(boundsThumb);
			ImageIcon icon = (ImageIcon)gamesThumbs.get(i).getIcon();
			try{
				gamesThumbs.get(i).setIcon(new ImageIcon(getScaledImage(ImageIO.read(new File(wrapper[i].thumbPath)),boundsThumb.width,boundsThumb.height)));
			}catch(Exception e){}
			gamesThumbs.get(i).setBorder(compound);
			pane.add(gamesThumbs.get(i),new Integer(1));
			y+=thumbnailSize.height + 10;
		}
		setLanguageButton(x, 5, thumbnailSize.width, 20);
	}
	private void insertExitButton(){
		exitButton = new JButton();
		exitButton.setIcon(new ImageIcon(getScaledImage(exit, control.height - offset.height, control.height - offset.height)));
		exitButton.setBorder(compound);
		exitButton.setBounds(5, control.y - offset.y, control.height, control.height - offset.height);
		exitButton.addActionListener(new ExitButtonListener());
		pane.add(exitButton, new Integer(1));
	}
	Rectangle offset = new Rectangle(0,-10,10,15);
	private void insertImage(Rectangle bounds){
		pane.remove(gamePhoto);
		ImageIcon icon = (ImageIcon)gamePhoto.getIcon();
		
		Rectangle newBounds = new Rectangle();
		newBounds.x = bounds.x - offset.x;
		newBounds.y = bounds.y - offset.y;
		newBounds.width = bounds.width - offset.width;
		newBounds.height = bounds.height - offset.height;
		gamePhoto.setBounds(newBounds);
		try{
			gamePhoto.setIcon(new ImageIcon(getScaledImage(ImageIO.read(new File(wrapper[currentWrapperIndex].imagePath)),newBounds.width,newBounds.height)));
		}catch(Exception e){
			
		}
		gamePhoto.setBorder(compound);
		pane.add(gamePhoto,new Integer(1));
	}
	JScrollPane areaScrollPane = null;
	private void insertText(Rectangle bounds){
		Rectangle newBounds = new Rectangle();
		newBounds.x = bounds.x - offset.x;
		newBounds.y = bounds.y - offset.y;
		newBounds.width = bounds.width - offset.width;
		newBounds.height = bounds.height - offset.height;
		if(areaScrollPane != null)pane.remove(areaScrollPane);
		//JTextArea textArea = new JTextArea(wrapper[currentWrapperIndex].text);
		JTextArea textArea = new JTextArea(gameInfo[currentWrapperIndex]);
		textArea.setEditable(false);
		textArea.setBackground(Color.white);
        textArea.setFont(new Font("Serif", Font.ITALIC, 16));
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        areaScrollPane = new JScrollPane(textArea);
        areaScrollPane.setVerticalScrollBarPolicy(
                        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        areaScrollPane.setBounds(newBounds);
        areaScrollPane.setBorder(compound);
        areaScrollPane.setBackground(Color.white);
        pane.add(areaScrollPane,new Integer(1));

	}
	JButton nextPage;
	JButton quickLoad;
	private void insertControl(Rectangle bounds){
		if(nextPage != null)pane.remove(nextPage);
		if(quickLoad != null)pane.remove(quickLoad);
		nextPage = new JButton(gameNames[currentWrapperIndex]);
		quickLoad = new JButton(mainDict.translate(Phrases.main_quickStart));
		Rectangle nextPageBounds = new Rectangle();
		nextPageBounds.x = bounds.x - offset.x;
		nextPageBounds.y = bounds.y - offset.y;
		nextPageBounds.width = (bounds.width - offset.width)/2-3;
		nextPageBounds.height = bounds.height - offset.height;
		Rectangle quickLoadBounds = new Rectangle();
		quickLoadBounds.x = bounds.x - offset.x+nextPageBounds.width+6;
		quickLoadBounds.y = bounds.y - offset.y;
		quickLoadBounds.width = (bounds.width - offset.width)/2-3;
		quickLoadBounds.height = bounds.height - offset.height;
		nextPage.setBounds(nextPageBounds);
		nextPage.addActionListener(new ButtonListener());
		quickLoad.setBounds(quickLoadBounds);
		quickLoad.addActionListener(new QuickstartButtonlistener());
		nextPage.setBorder(compound);
		quickLoad.setBorder(compound);
		pane.add(quickLoad,new Integer(1));
		pane.add(nextPage,new Integer(1));
	}
	@Override
	public void paint(Graphics g) {
		super.paint(g);
	}
	public void setFrameReference(JFrame frame){
		this.frameReference = frame;
	}
	class ButtonListener implements ActionListener{

		@Override
		public void actionPerformed(ActionEvent button) {
			
			observableObject.setResult(games[currentWrapperIndex]);
			observableObject.notifyObservers();
		}
	}
	class QuickstartButtonlistener extends ButtonListener{
		@Override
		public void actionPerformed(ActionEvent button) {
			games[currentWrapperIndex].setQuickStart(true);
			super.actionPerformed(button);
		}
	}
	private GameWrapper[]  createGameWrapper(File  imagePath, GameProperty[] games ){
		String filePath = imagePath.getAbsolutePath();
		GameWrapper[] wrapper = new GameWrapper[games.length];
		for(int i = 0; i<wrapper.length;i++)
		{
			wrapper[i]= new GameWrapper(games[i].getDisplayName(),
					filePath+File.separator+"info_"+games[i].getName()+".png",
					filePath+File.separator+"2auftritt_"+games[i].getName()+".png",
					games[i].getDisplayName()+", a super game");
		}
		return wrapper;
	}
	
	private class GameWrapper {
    	public String name;
    	public String imagePath;
    	public String thumbPath;
    	public String text;
		public GameWrapper(String name, String imagePath, String thumbPath, String text) {
			super();
			this.name = name;
			this.thumbPath = thumbPath;
			this.imagePath = imagePath;
			this.text = text;
		}
    }
	/**
     * SwingWorker class that loads the images a background thread and calls publish
     * when a new one is ready to be displayed.
     *
     * We use Void as the first SwingWroker param as we do not need to return
     * anything from doInBackground().
     */
    private SwingWorker<Void, ThumbnailAction> loadimages = new SwingWorker<Void, ThumbnailAction>() {
        
        /**
         * Creates full size and thumbnail versions of the target image files.
         */
        @Override
        protected Void doInBackground() throws Exception {
            System.err.println("Background");
        	for (int i = 0; i < wrapper.length; i++) {
                ImageIcon icon;
                ImageIcon thumb;
                icon = createImageIcon(wrapper[i].imagePath, wrapper[i].name);
                thumb = createImageIcon(wrapper[i].thumbPath, wrapper[i].name);
                ThumbnailAction thumbAction;
                if(icon != null){
                    
                    ImageIcon thumbnailIcon = new ImageIcon(getScaledImage(thumb.getImage(), thumbnailSize.width, thumbnailSize.height));
                    if(i == 0){
                    	currentWrapperIndex = 0;
                    }
                    thumbAction = new ThumbnailAction(icon, thumbnailIcon, wrapper[i].name,i );
                    publish(thumbAction);
                }
                
            }
    		
            // unfortunately we must return something, and only null is valid to
            // return when the return type is void.
            return null;
        }
        
        /**
         * Process all loaded images.
         */
        @Override
        protected void process(List<ThumbnailAction> chunks) {
            for (ThumbnailAction thumbAction : chunks) {
                JButton thumbButton = new JButton(thumbAction);
                // add the new button BEFORE the last glue
                // this centers the buttons in the toolbar
                gamesThumbs.add(thumbButton);
            }
            calculateGeneralBounds();	
        }
    };
    
    /**
     * Creates an ImageIcon if the path is valid.
     * @param String - resource path
     * @param String - description of the file
     */
    protected ImageIcon createImageIcon(String path,
            String description) {
        Image img = null;
		try {
			img = ImageIO.read(new File(path));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        if (img != null) {
            return new ImageIcon(img, description);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }
    
    /**
    private Image getScaledImage(Image srcImg, int w, int h){
        BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = resizedImg.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2.drawImage(srcImg, 0, 0, w, h, null);
        g2.dispose();
        return resizedImg;
    }*/
    
    /**
     * Action class that shows the image specified in it's constructor.
     */
    private class ThumbnailAction extends AbstractAction{
        
        /**
         *The icon if the full image we want to display.
         */
        private Icon displayPhoto;
        private int index;
        
        /**
         * @param Icon - The full size photo to show in the button.
         * @param Icon - The thumbnail to show in the button.
         * @param String - The descriptioon of the icon.
         */
        public ThumbnailAction(Icon photo, Icon thumb, String desc, int index){
            displayPhoto = photo;
            this.index = index;
            // The short description becomes the tooltip of a button.
            putValue(SHORT_DESCRIPTION, desc);
            
            // The LARGE_ICON_KEY is the key for setting the
            // icon when an Action is applied to a button.
            putValue(LARGE_ICON_KEY, thumb);
        }
        
        /**
         * Shows the full image in the main area and sets the application title.
         */
        public void actionPerformed(ActionEvent e) {
        	currentWrapperIndex = index;
        	calculateGeneralBounds();
        	System.err.println("Button was pressed");
            
            //setTitle("Icon Demo: " + getValue(SHORT_DESCRIPTION).toString());
        }
    }
    
    private class ExitButtonListener extends ButtonListener{
		@Override
		public void actionPerformed(ActionEvent button) {
			System.exit(0);
		}
    }
}
